<!DOCTYPE html>
<html>

<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
    <style type="text/css">
        body,
        html,
        #allmap {
            width: 100%;
            height: 100%;
            overflow: hidden;
            margin: 0;
            font-family: "微软雅黑";
        }

        #dashboard {
            position: fixed;
            top: 0;
            height: 100%;
            width: 14%;
            right: 0;
            z-index: 99;
            background-color: white;
            opacity: 80%;
        }

        .block {
            height: 20%;
            width: 100%;
            background-color: white;
        }
    </style>
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
    <script src="https://cdn.staticfile.org/echarts/5.0.0/echarts.min.js"></script>
    <link rel="shortcut icon" href="./favicon.ico">
    <!-- <script type="text/javascript" src="//api.map.baidu.com/api?v=2.0&ak=DUS3zgcXlPG5gyjfdSra8NfpOblj7Ggr"></script> -->
    <script type="text/javascript"
        src="https://api.map.baidu.com/api?v=1.0&type=webgl&ak=DUS3zgcXlPG5gyjfdSra8NfpOblj7Ggr"></script>

    <!-- <link rel="icon" href="./favicon.ico" mce_href="./favicon.ico" type="image/x-icon">  
    <link rel="shortcut icon" href="./favicon.ico" mce_href="./favicon.ico" type="image/x-icon">   -->
    <title>船舶交通流仿真平台</title>
</head>

<body>
    <div id="allmap"></div>
    <div id="dashboard">
        <div id="shipInfo" class="block">
            <table style="text-align:left;height:100%;">
                <tbody>
                    <tr>
                        <th>shipName:</th>
                        <th id="shipName"></th>
                    </tr>
                    <tr>
                        <th>MMSI:</th>
                        <th id="MMSI"></th>
                    </tr>
                    <tr>
                        <th>SimClock:</th>
                        <th id="simClock"></th>
                    </tr>
                    <tr>
                        <th>LON:</th>
                        <th id="LON"></th>
                    </tr>
                    <tr>
                        <th>LAT:</th>
                        <th id="LAT"></th>
                    </tr>
                </tbody>
            </table>
        </div>
        <div id="VO" class="block">
            <svg xmlns="http://www.w3.org/2000/svg" viewbox="-100 -100 200 200">
                <text x="-50" y="-60" font-family="Verdana" font-size="12">Velocity Obstacle</text>
                <circle id="Circle" cx="0" cy="0" r="50" stroke="white" stroke-width="0" fill="white" />

                <path id="A2" stroke="#F4D03F" stroke-width="1" fill="#F4D03F" />
                <path id="A3" stroke="#F4D03F" stroke-width="1" fill="#F4D03F" />
                <!-- <path id="A4" stroke="#2ECC71" stroke-width="1" fill="#2ECC71" /> -->
                <path id="A1" stroke="#E74C3C" stroke-width="0" fill="#E74C3C" />

                <defs>
                    <marker id="arrow" markerWidth="4" markerHeight="4" refx="2" refy="2" orient="auto"
                        markerUnits="strokeWidth">
                        <path id="arrow_body" d="M 0 0 L 0 4 L 4 2 Z" fill="#212F3D" />
                    </marker>
                </defs>>
                <line id="speedLine" x1="0" y1="0" y2="0" stroke="#212F3D" marker-end="url(#arrow)" stroke-width="1.5"
                    transform="rotate(20)" />
                <!-- 绘制白色下半圆 遮住原来的半圆 -->
                <path id="Cover" stroke-width="2" stroke="white" fill="white" />
                <circle id="P1" r="1" stroke="black" stroke-width="2" />

                <!-- 遮瑕用的 -->
                <circle id="poly" r="5" stroke="transparent" fill="white" />
            </svg>
        </div>
        <div id="riskValue" class="block">Risk value</div>
        <div id="TCPA" class="block"> TCPA</div>
        <div id="DCPA" class="block"> hello</div>
    </div>

    <script type="text/javascript">
        // 百度地图API功能
        var map = new BMapGL.Map("allmap");
        // map.centerAndZoom(new BMapGL.Point(118.765052, 32.137083), 14);
        map.centerAndZoom(new BMapGL.Point(118.6224279, 31.94938), 17);
        map.enableScrollWheelZoom(); // 使能缩放

        // DCPA
        var chartDomDcpa = document.getElementById("DCPA");
        var myChartDcpa = echarts.init(chartDomDcpa);
        var optionDcpa;
        optionDcpa = {
            series: [{
                min: -10000,
                max: 10000,
                type: 'gauge',
                progress: {
                    show: true,
                    width: 8
                },
                axisLine: {
                    lineStyle: {
                        width: 8
                    }
                },
                axisTick: {
                    show: false
                },
                splitLine: {
                    show: true,
                    length: 5,
                    distance: 2,
                    lineStyle: {
                        width: 2,
                        color: '#999'
                    }
                },
                axisLabel: {
                    distance: 10,
                    color: '#999',
                    fontSize: 10
                },
                anchor: {
                    show: true,
                    showAbove: true,
                    size: 10,
                    itemStyle: {
                        borderWidth: 5
                    }
                },
                detail: {
                    valueAnimation: false,
                    fontSize: 15,
                    offsetCenter: [0, '80%']
                },
                data: [{
                    value: 1930.74,
                    name: "DCPA",
                    title: {
                        show: true,
                        offsetCenter: [0, "-120%"],
                        fontSize: 15
                    },
                    fontSize: 15
                }]
            }]
        };
        optionDcpa && myChartDcpa.setOption(optionDcpa);

        // TCPA
        var chartDomTcpa = document.getElementById("TCPA");
        var myChartTcpa = echarts.init(chartDomTcpa);
        var optionTcpa;
        optionTcpa = {
            series: [{
                min: -2000,
                max: 2000,
                type: 'gauge',
                progress: {
                    show: true,
                    width: 8,
                    itemStyle: {
                        color: "#7DCEA0"
                    }
                },
                axisLine: {
                    lineStyle: {
                        width: 8
                    }
                },
                axisTick: {
                    show: false
                },
                splitLine: {
                    show: true,
                    length: 5,
                    distance: 2,
                    lineStyle: {
                        width: 2,
                        color: '#999'
                    }
                },
                axisLabel: {
                    distance: 10,
                    color: '#999',
                    fontSize: 10
                },
                anchor: {
                    show: true,
                    showAbove: true,
                    size: 10,
                    itemStyle: {
                        borderWidth: 5,
                        bprderColor: "#7DCEA0"
                    }
                },
                pointer: {
                    itemStyle: {
                        color: '#7DCEA0'
                    }
                },
                detail: {
                    valueAnimation: false,
                    fontSize: 15,
                    offsetCenter: [0, '80%']
                },
                data: [{
                    value: 502.28,
                    name: "TCPA",
                    title: {
                        show: true,
                        offsetCenter: [0, "-120%"],
                        fontSize: 15
                    },
                    fontSize: 15
                }]
            }]
        };
        optionTcpa && myChartTcpa.setOption(optionTcpa);

        // risk value
        var chartDomRisk = document.getElementById("riskValue");
        var myChartRisk = echarts.init(chartDomRisk);
        var optionRisk;
        optionRisk = {
            series: [{
                min: 0,
                max: 1,
                type: 'gauge',
                progress: {
                    show: true,
                    width: 8,
                    itemStyle: {
                        color: "#D98880"
                    }
                },
                axisLine: {
                    lineStyle: {
                        width: 8
                    }
                },
                axisTick: {
                    show: false
                },
                splitLine: {
                    show: true,
                    length: 5,
                    distance: 2,
                    lineStyle: {
                        width: 2,
                        color: '#999'
                    }
                },
                axisLabel: {
                    distance: 10,
                    color: '#999',
                    fontSize: 10
                },
                anchor: {
                    show: true,
                    showAbove: true,
                    size: 10,
                    itemStyle: {
                        borderWidth: 5,
                        bprderColor: "#D98880"
                    }
                },
                pointer: {
                    itemStyle: {
                        color: '#D98880'
                    }
                },
                detail: {
                    valueAnimation: false,
                    fontSize: 15,
                    offsetCenter: [0, '80%']
                },
                data: [{
                    value: 0.1074,
                    name: "Risk",
                    title: {
                        show: true,
                        offsetCenter: [0, "-120%"],
                        fontSize: 15
                    },
                    fontSize: 15
                }]
            }]
        };
        optionRisk && myChartRisk.setOption(optionRisk);

        // 绘制VO
        function parseArgs(args) {
            let points = [];
            // 设定调节图形大小的系数
            let k = 2.5;
            let res = args.VOPxy;
            // console.log(args);
            for (let index in res) {
                points.push({
                    lon: (res[index][0] * k),
                    lat: (res[index][1] * k)
                })
            }
            if (args.speed < 4) {
                tspeed = args.speed * 4 * k - 2;
            } else if (args.speed < 8) {
                tspeed = args.speed * 2 * k - 2;
            } else {
                tspeed = args.speed * k - 2;
            }
            return {
                k: k,
                points: points,
                radius: args.radius * k,
                speed: tspeed,
                heading: args.head - 90
            };
        }

        function drawVo(args) {
            // 判断状态
            let status = args.status;
            if (status == 0) {

            } else if (status == 1) {

            } else if (status == -1) {

            }
            let tmp = parseArgs(args);
            let k = tmp.k;
            let points = tmp.points;
            let radius = tmp.radius;
            let speed = tmp.speed;
            let heading = tmp.heading;

            let p0 = points[0];
            let p1 = points[1];
            let p2 = points[2];
            let p3 = points[3];
            let p4 = points[4];
            let p5 = points[5];
            let p6 = points[6];
            let p7 = points[7];
            let p8 = points[8];
            let normPointArray = [p0, p1, p2, p3, p4, p5, p6, p7, p8];

            // 下面开始绘图
            // 绘制圆 可省略
            let Circle = document.getElementById("Circle");
            Circle.setAttribute("fill", "#2ECC71");
            // Circle.style.cx = normPointArray[1].lon.toString();
            // Circle.style.cy = normPointArray[1].lat.toString();
            // Circle.style.r = radius;
            let poly = document.getElementById("poly");
            poly.style.fill = "transparent";

            // 分别绘制4个区域
            let A2 = document.getElementById("A2");
            A2.setAttribute("d", `M ${normPointArray[2].lon} ${normPointArray[2].lat} L ${normPointArray[3].lon} ${normPointArray[3].lat} A ${radius} ${radius} 0 0 0 ${normPointArray[5].lon} ${normPointArray[5].lat} Z`)

            let A3 = document.getElementById("A3");
            A3.setAttribute("d", `M ${normPointArray[2].lon} ${normPointArray[2].lat} L ${normPointArray[6].lon} ${normPointArray[6].lat} A ${radius} ${radius} 0 0 0 ${normPointArray[4].lon} ${normPointArray[4].lat} Z`)

            // let A4 = document.getElementById("A4");
            // A4.setAttribute("d", `M ${normPointArray[2].lon} ${normPointArray[2].lat} L ${normPointArray[4].lon} ${normPointArray[4].lat} A ${radius} ${radius} 0 0 0 ${normPointArray[3].lon} ${normPointArray[3].lat} Z`)

            let A1 = document.getElementById("A1");
            A1.setAttribute('d', `M ${normPointArray[2].lon} ${normPointArray[2].lat} L ${normPointArray[5].lon} ${normPointArray[5].lat} A ${radius} ${radius} 0 0 0 ${normPointArray[6].lon} ${normPointArray[6].lat} Z`);

            // 绘制P1 中心点
            let P1 = document.getElementById("P1");
            P1.style.cx = normPointArray[1].lon.toString();
            P1.style.cy = normPointArray[1].lat.toString();
            if (k < 2) {
                // P1.style.stroke-width = "2";
                P1.setAttribute("stroke-width", "1");
            }

            // 绘制速度矢量
            let speedLine = document.getElementById("speedLine");
            speedLine.setAttribute("x2", `${speed}`);
            speedLine.setAttribute("transform", `rotate(${heading})`);

            // 绘制下半圆遮盖物
            // let Cover = document.getElementById("Cover");
            // Cover.setAttribute("d", `M ${normPointArray[1].lon} ${normPointArray[1].lat} L ${normPointArray[7].lon} ${normPointArray[7].lat} A ${radius} ${radius} 0 0 0 ${normPointArray[8].lon} ${normPointArray[8].lat}`);

        }
        let args = {
            "VOPxy": [[94.52317246766864, 111.3763884589862], [0, 0], [5.000000000710581, -8.660254038167059], [-17.209872196534498, 10.189224651815314], [12.851883956418277, -15.324133866577933], [15.998927009258402, 12.001430521367292], [19.999635936012922, -0.12067486577087888], [6.840402866906618, -18.79385241669232], [-6.840402865397154, 18.793852414984354]],
            "radius": 20, "speed": 15, "head": 115, "status": 0
        };
        drawVo(args);

        var myIcon1 = new BMapGL.Icon("/static/icons/1-15-30.svg", new BMapGL.Size(20, 33), {
            imageOffset: new BMapGL.Size(0, 0)    //图片的偏移量。为了是图片底部中心对准坐标点。
        });
        var myIcon2 = new BMapGL.Icon("/static/icons/2-15-25.svg", new BMapGL.Size(20, 33), {
            imageOffset: new BMapGL.Size(0, 0)    //图片的偏移量。为了是图片底部中心对准坐标点。
        });
        var myIcon3 = new BMapGL.Icon("/static/icons/3-15-30.svg", new BMapGL.Size(20, 33), {
            imageOffset: new BMapGL.Size(0, 0)    //图片的偏移量。为了是图片底部中心对准坐标点。
        });
        var myIcon4 = new BMapGL.Icon("/static/icons/4-15-25.svg", new BMapGL.Size(20, 33), {
            imageOffset: new BMapGL.Size(0, 0)    //图片的偏移量。为了是图片底部中心对准坐标点。
        });
        var myIcon5 = new BMapGL.Icon("/static/icons/5-15-25.svg", new BMapGL.Size(20, 33), {
            imageOffset: new BMapGL.Size(0, 0)    //图片的偏移量。为了是图片底部中心对准坐标点。
        });
        var myIcon6 = new BMapGL.Icon("/static/icons/6-15-25.svg", new BMapGL.Size(20, 33), {
            imageOffset: new BMapGL.Size(0, 0)    //图片的偏移量。为了是图片底部中心对准坐标点。
        });
        var myIcon = [myIcon1, myIcon2, myIcon3, myIcon4, myIcon5, myIcon6];

        function get_path(start_point, end_point, rd, delta = 0.0002) {
            // 在路径上均匀采样 uniform_sampling, 采样间隔为delta. 横纵坐标(经纬度)按照相似三角形计算.
            // console.log("get_path was called.");
            let distance = Math.hypot(
                end_point[0] - start_point[0],
                end_point[1] - start_point[1]
            )
            if (distance > delta) {
                path = [];
                let N = Math.abs(parseInt(distance / delta));
                for (let i = 0; i < N; i++) {
                    // 根据形似三角形计算某个场景下经纬度的delta
                    delta_x = (delta / distance) * (end_point[0] - start_point[0]);
                    delta_y = (delta / distance) * (end_point[1] - start_point[1]);
                    // N从0到N-1 包含起点, 不含终点
                    path.push(new BMapGL.Point(start_point[0] + delta_x * i + rd, start_point[1] + delta_y * i));
                }
                path.push(new BMapGL.Point(end_point[0] + rd, end_point[1]));
            } else {
                path = [new BMapGL.Point(start_point[0] + rd, start_point[1]), new BMapGL.Point(end_point[0] + rd, end_point[1])];
            }
            return path
        }

        function get_line(my_line, rd) {
            // console.log("get_line was called.");
            let line = [];
            let td = rd;
            for (let k = 0; k < my_line.length - 1; k++) {
                let path = get_path(my_line[k], my_line[k + 1], rd);
                // console.log(path[0]);
                for (let n = 0; n < path.length; n++) {
                    // console.log(path[n]);
                    line.push(path[n]);
                }
            }
            return line;
        }

        function get_angle(lng1, lat1, lng2, lat2, flag = "up") {
            // console.log("called get angle.")
            // console.log(lng1, lat1)
            if (flag == "up") {
                var mod = function (n, m) {
                    var remain = n % m;
                    return 180 + Math.floor(remain >= 0 ? remain : remain + m);
                };
            } else {
                var mod = function (n, m) {
                    var remain = n % m;
                    return Math.floor(remain >= 0 ? remain : remain + m);
                };
            }

            let x = Math.abs(lng1 - lng2);
            let y = Math.abs(lat1 - lat2);
            let z = Math.sqrt(x * x + y * y);
            // console.log(Math.asin(y / z) / Math.PI);
            let angle = Math.round(Math.asin(y / z) / Math.PI * 180);
            // console.log(mod(90 - angle, 360));
            return mod(90 - angle, 360);
        }

        function myAddOverlay(map, ship) {
            // console.log("ship: ", ship);
            let icon = new BMapGL.Icon("static/5-15-25.svg", new BMapGL.Size(15, 25), {
                imageOffset: new BMapGL.Size(0, 0)    //图片的偏移量。为了是图片底部中心对准坐标点。
            });
            let pt = new BMapGL.Point(ship.lon, ship.lat);
            let shipMarker = new BMapGL.Marker(pt, {
                icon: icon,
                // rotation: 245,
            });
            shipMarker.setRotation(ship.head + map.getHeading());
            shipMarker.addEventListener("onclick", function () {
                selectedShipMmsi = ship.mmsi;
            })
            // 向地图添加图标
            map.addOverlay(shipMarker);
        }

        function getRandomInt(min, max) {
            min = Math.ceil(min);
            max = Math.floor(max);
            return Math.floor(Math.random() * (max - min)) + min; //不含最大值，含最小值
        }

        let shipTable = {
            "10001": 3
        }

        function shipExistsInShipTable(shipMmsi) {
            // mmsi should be a str, like "213456432"
            return shipTable.hasOwnProperty(shipMmsi);
        }

        function encapsulateShipToMarker(ship, iconId = -1) {
            // 将ship对象封装为Marker
            let rand = -1;
            if (iconId == -1) {
                rand = getRandomInt(0, myIcon.length);
            }
            else {
                rand = iconId;
            }
            let icon = myIcon[rand];
            let pt = new BMapGL.Point(ship.LON, ship.LAT);
            let Marker = new BMapGL.Marker(pt, {
                icon: icon,
                // rotation: 245,
            });
            Marker.setRotation(ship.THEADING + map.getHeading());
            Marker.addEventListener("onclick", function () {
                selectedShipMmsi = ship.SHIP_CODE;
            })
            return { // rich marker
                marker: Marker,
                mmsi: ship.SHIP_CODE,
                iconId: rand
            };
        }

        function addShipMarkerIntoShipTable(richMarker) {
            // ship (richMarker) should be an object with full infomation
            shipTable[richMarker.mmsi] = richMarker.iconId;
        }

        function addShipMarkerIntoBMap(map, richMarker) {
            map.addOverlay(richMarker.marker);
        }

        // function updateShipStatusInShipTable(ship) {
        //     // ship
        //     shipTable.mmsi = ship;
        // }

        var selectedShipMmsi = "0";
        setInterval(function () {
            $.ajax({
                url: "/data/slice",
                success: function (data) {
                    // 遍历data中的船，如果不再ship_table中，就添加进去，否则更新位置
                    map.clearOverlays(); // 清除上一步的Marker
                    for (let i = 0; i < data.length; i++) {
                        let ship = data[i];
                        let iconId = -1;
                        if (shipExistsInShipTable(ship.SHIP_CODE)) {
                            iconId = shipTable[ship.SHIP_CODE];
                            var richMarker = encapsulateShipToMarker(ship, iconId);

                        }
                        else {
                            var richMarker = encapsulateShipToMarker(ship, iconId);
                            addShipMarkerIntoShipTable(richMarker);
                        }
                        addShipMarkerIntoBMap(map, richMarker);
                        // Dashboard
                        if (ship.SHIP_CODE == selectedShipMmsi) {
                            $("#shipName").text(ship.SN);
                            $("#MMSI").text(ship.SHIP_CODE);
                            // $("#simClock").text(ship.Time);
                            $("#LON").text(ship.LON.toFixed(6));
                            $("#LAT").text(ship.LAT.toFixed(6));
                            // drawVo(ship.VOargs); // 绘制VO图
                            // optionDcpa.series[0].data[0].value = ship.DCPA.toFixed(4);
                            // optionDcpa && myChartDcpa.setOption(optionDcpa);
                            // optionTcpa.series[0].data[0].value = ship.TCPA.toFixed(4);
                            // optionTcpa && myChartTcpa.setOption(optionTcpa);
                            // optionRisk.series[0].data[0].value = ship.collision_risk.toFixed(4)
                            // optionRisk && myChartRisk.setOption(optionRisk);
                        }
                    }

                }
            });
        }, 1000);

        function test() {
            $.ajax({
                url: "/data/test",
                success: function (data) {
                    // 遍历data中的船，如果不再ship_table中，就添加进去，否则更新位置
                    map.clearOverlays(); // 清除Marker
                    for (let i = 0; i < data.length; i++) {
                        let ship = data[i];
                        let iconId = -1;
                        if (shipExistsInShipTable(ship.SHIP_CODE)) {
                            iconId = shipTable[ship.SHIP_CODE];
                            var richMarker = encapsulateShipToMarker(ship, iconId);

                        }
                        else {
                            var richMarker = encapsulateShipToMarker(ship, iconId);
                            addShipMarkerIntoShipTable(richMarker);
                        }
                        addShipMarkerIntoBMap(map, richMarker);
                    }
                }
            });
        }
        // test();
    </script>

</body>
</html>